package btc

import (
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"os"

	"path"
)

type Wallet struct {
	Type            string              `json:"wallet_type"`
	Addresses       map[string]struct{} `json:"addresses"`
	Addr_history    map[string]struct{} `json:"addr_history"`
	Spent_outpoints map[string]struct{} `json:"spent_outpoints"`
	Transactions    map[string]struct{} `json:"transactions"`
	Tx_fees         map[string]struct{} `json:"tx_fees"`
	Txi             map[string]struct{} `json:"txi"`
	Txo             map[string]struct{} `json:"txo"`
	Use_encryption  bool                `json:"use_encryption"`
	Verified_tx3    map[string]struct{} `json:"verified_tx3"`
	Seed_version    int64               `json:"seed_version"`
}

func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func (w *Wallet) Marshal() ([]byte, error) {
	buf, err := json.Marshal(w)
	if err != nil {
		return nil, err
	}
	var out bytes.Buffer
	err = json.Indent(&out, buf, "", "\t")
	if err != nil {
		return nil, err
	}
	return out.Bytes(), nil
}

func (w *Wallet) WriteFile(filename string) error {
	buf, err := w.Marshal()
	if err != nil {
		return err
	}
	return ioutil.WriteFile(filename, buf, 0755)
}

//创建钱包
func MakeWallet(addrs map[int]string) error {
	datadir := ""

	if CommandGlobal.Testnet == 0 {
		datadir = path.Join(CommandGlobal.Datadir, "wallets")
	} else {
		datadir = path.Join(CommandGlobal.Datadir, "testnet", "wallets")
	}

	// 清理旧钱包数据
	exists, _ := PathExists(CommandGlobal.Datadir)
	if exists == true {
		err := os.RemoveAll(CommandGlobal.Datadir)
		if err != nil {
			return err
		}
	}
	err := os.MkdirAll(datadir, 0777)
	if err != nil {
		return err
	}

	// 构建新钱包
	wallet := new(Wallet)
	wallet.Type = "imported"
	wallet.Addr_history = map[string]struct{}{}
	wallet.Spent_outpoints = map[string]struct{}{}
	wallet.Transactions = map[string]struct{}{}
	wallet.Tx_fees = map[string]struct{}{}
	wallet.Txi = map[string]struct{}{}
	wallet.Txo = map[string]struct{}{}
	wallet.Verified_tx3 = map[string]struct{}{}
	wallet.Use_encryption = false
	wallet.Seed_version = 18
	wallet.Addresses = map[string]struct{}{}

	for _, addr := range addrs {
		wallet.Addresses[addr] = struct{}{}
	}
	err = wallet.WriteFile(path.Join(datadir, "default_wallet"))
	if err != nil {
		return err
	}
	return nil
}

func InitBtcElecTrum(addrs map[int]string) error {

	err := CommandGlobal.DaemonStop()
	if err != nil {
		return errors.New("btc electrum DaemonStop error" + err.Error())
	}
	err = MakeWallet(addrs)
	if err != nil {
		return errors.New("btc electrum MakeWallet error" + err.Error())
	}

	err = CommandGlobal.DaemonStart()
	if err != nil {
		return errors.New("btc electrum DaemonStart error" + err.Error())
	}
	err = CommandGlobal.DaemonLoad()
	if err != nil {
		return errors.New("btc electrum DaemonLoad error---" + err.Error())
	}
	return nil

}
